﻿using System;
using System.Linq;
using Apollo;
using Apollo.Core;
using NHibernate.Mapping;
using System.Collections.Generic;
using NHibernate;

namespace Apollo.Website
{
    public partial class View : System.Web.UI.Page
    {
        public const string APOLLO_ENTITY_ACTION = "APOLLO_ENTITY_ACTION";
        public const string APOLLO_USER_VIEW_ADD = "APOLLO_USER_VIEW_ADD";
        public const string APOLLO_USER_VIEW_DEL = "APOLLO_USER_VIEW_DEL";

        protected MenuItem SelectedMenuItem { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            int menuId = 0;

            // Normal view
            if (int.TryParse(this.Request["MenuId"], out menuId))
            {
                SelectedMenuItem = Apollo.Application.Meta<MenuItem>()
                            .SingleOrDefault<MenuItem>(m => m.Id == menuId);

                if (SelectedMenuItem != null && SelectedMenuItem.EntityView != null)
                    EntityGridView.EntityView = SelectedMenuItem.EntityView;

                if (SelectedMenuItem != null)
                {
                    LanguageDefinition ld = Apollo.Application.Meta<LanguageDefinition>()
                    .SingleOrDefault<LanguageDefinition>(l => l.Type == "MenuItem"
                        && l.CodeHi == SelectedMenuItem.Id.ToString()
                        && l.Language.Id == Apollo.Application.CurrentLanguage.Id);

                    this.Title = ld != null ? ld.DisplayName : SelectedMenuItem.Name;
                }

                EntityGridView.Columns = this.Request["c"];
            }

            // User defined view
            if (!string.IsNullOrEmpty(this.Request["UserViewId"]))
            {
                try
                {
                    UserView uview = Apollo.Application.CurrentSession.QueryOver<UserView>()
                        .Where(u => u.Id == int.Parse(this.Request["UserViewId"]))
                        .SingleOrDefault();

                    if (uview != null)
                    {
                        EntityGridView.EntityView = null;
                        EntityGridView.UserView = uview;
                    }

                }
                catch (Exception ex)
                {
                    MessageList.AddMessage(new ActionMessage("UserView error: " + ex.Message));
                }
            }

            // Parse the filter string
            if (!string.IsNullOrEmpty(this.Request["f"])) {
                FilterGroup group = WebHelper.DeserializeGroupFromJSON(
                    this.Request["f"],
                    EntityGridView.EntityView != null ? EntityGridView.EntityView.Entity.MappedClass
                            : EntityGridView.UserView.Entity.MappedClass);

                if (!group.IsEmpty) {
                    EntityGridView.FilterString = WebHelper.SerializeGroupToJSON(group);

                    // format it to be used in javascript code
                    EntityGridView.FilterString = EntityGridView.FilterString.Replace("\\", "\\\\").Replace("\"", "\\\"");
                }
            }

            string actionsJScrips = EntityGridView.EntityView != null ? GetJavaScriptForActions(EntityGridView.EntityView.Entity) : "";

            LiteralJS.Text = @"
    <script type=""text/javascript"">
        $(document).ready(function() {
            " + EntityGridView.GetJavaScriptMethodDefinition() + @"
            " + actionsJScrips + @"
            " + GetJavaScriptForUserView() + @"
        });
    </script>
";

            // check if it is a post back from an action
            if (this.Request.Form["__EVENTTARGET"] == APOLLO_ENTITY_ACTION)
                this.DoAction(this.Request.Form["__EVENTARGUMENT"], null);

            if (this.Request.Form["__EVENTTARGET"] == APOLLO_USER_VIEW_ADD)
                this.OnUserViewAdd(this.Request.Form["__EVENTARGUMENT"]);

            if (this.Request.Form["__EVENTTARGET"] == APOLLO_USER_VIEW_DEL)
                this.OnUserViewDel();
        }

        protected string GetJavaScriptForActions(Entity entity)
        {
            string actionsJavaScript = "";

            foreach (EntityAction action in Apollo.Application.Meta<EntityAction>().Where<EntityAction>(ea => ea.Entity.Id == entity.Id && (ea.Applicability == EntityActionApplicability.List || ea.Applicability == EntityActionApplicability.Global)))
            {
                actionsJavaScript += @"
    // add action " + action.Name + @"
    $(""#entity_menu" + EntityGridView.Prefix + @""").append(CreateMenuItem("" " + action.Name + @""",""" + action.IconPath + @""", null, function() {
        __doPostBack('" + APOLLO_ENTITY_ACTION + "','" + action.Code + @"');
    }));
            ";
            }

            return actionsJavaScript;
        }

        protected string GetJavaScriptForUserView()
        {
            if (this.EntityGridView.EntityView != null)
            {
                if (!Apollo.Application.Current.IsAllowed(Apollo.Application.ACTION_SAVE_VIEW_NAME, this.EntityGridView.EntityView.Entity, null))
                    return "";
            }
            else if (this.EntityGridView.UserView != null)
            {
                if (!Apollo.Application.Current.IsAllowed(Apollo.Application.ACTION_SAVE_VIEW_NAME, this.EntityGridView.UserView.Entity, null))
                    return "";
            }
            else
                return "";


            if (!Apollo.Application.Current.IsAllowed(
                Apollo.Application.ACTION_SAVE_VIEW_NAME
                , this.EntityGridView.EntityView != null ? this.EntityGridView.EntityView.Entity : this.EntityGridView.UserView.Entity
                , null))
                return "";

            string js = "";

            if (EntityGridView.UserView != null)
            {
                // add delete action
                js += @"
    $(""#entity_menu" + EntityGridView.Prefix + @""").append(CreateMenuItem("" Delete view"",""/css/icons/icon_46.png"", null, 
        function() {
            __doPostBack('" + APOLLO_USER_VIEW_DEL + @"','');
        }
    ));
            ";
            }
            else if (EntityGridView.EntityView != null)
            {
                // add create action
                js += @"
    $(""#entity_menu" + EntityGridView.Prefix + @""").append(CreateMenuItem("" Save view"",""/css/icons/icon_45.png"", null, 
        function() {
            $(""#dialog-prompt"" ).dialog({
			    modal: true,
			    buttons: {
				    Ok: function() {
                        var uvName = document.getElementById('dialog-prompt-name').value;

                        var gridEntity = $('#entity_list" + EntityGridView.Prefix + @"');

                        var postData = gridEntity.getGridParam('postData');

                        var gridFilterString = null;    // holds the filter that the user quicksearched
                        var requestFilterString = null; // holds the filter from QUERYSTRING
                        var filterString = """";

                        if (postData.filters) 
                            gridFilterString = postData.filters;

                        if (getParameterByName(""f""))
                            requestFilterString = getParameterByName(""f"");

                        if (gridFilterString || requestFilterString) {
                            if (gridFilterString) {
                                if (filterString && filterString != '')
                                    filterString += "","";

                                filterString += gridFilterString;
                            }

                            if (requestFilterString) {
                                if (filterString && filterString != '')
                                    filterString += "","";

                                filterString += requestFilterString;
                            }

                            filterString = '{""groupOp"":""AND"",""groups"":[' + filterString + '],""rules"":[]}';
                        }
                        
                        uvName = uvName + ""|"" 
                                + filterString + ""|"" 
                                + gridEntity.getGridParam('sortname') + ""|""
                                + gridEntity.getGridParam('sortorder');

                        __doPostBack('" + APOLLO_USER_VIEW_ADD + @"', uvName);

					    $(this).dialog(""close"");
				    }
			    }
		    });
        }
    ));
            ";
            }

            return js;
        }

        protected void DoAction(string actionCode, object obj)
        {
            ActionContext context = Apollo.Application.Current.DoAction(actionCode, obj);

            foreach (ActionMessage msg in context.Messages)
                this.MessageList.AddMessage(msg);
        }

        protected void OnUserViewAdd(string commandArgument)
        {
            ITransaction tran = Apollo.Application.CurrentSession.BeginTransaction();

            try
            {
                string[] viewArgs = commandArgument.Split("|".ToCharArray(), StringSplitOptions.None);

                string name = viewArgs[0];
                string filter = viewArgs[1];
                string orderBy = null;
                OrderDirection orderDirection = OrderDirection.Asc;
                string viewString = !string.IsNullOrEmpty(this.Request["c"]) ? this.Request["c"] : EntityGridView.EntityView.ViewString;

                if (!string.IsNullOrEmpty(viewArgs[2]))
                {
                    orderBy = viewArgs[2];
                    orderDirection = viewArgs[3].ToLower() == "asc" ? OrderDirection.Asc : OrderDirection.Desc;
                }

                User u = Apollo.Application.CurrentSession.Get<User>(Apollo.Application.CurrentUser.Id);

                UserView uv = new UserView()
                {
                    Entity = EntityGridView.EntityView != null ? EntityGridView.EntityView.Entity : EntityGridView.UserView.Entity,
                    Filter = filter,
                    MenuItem = SelectedMenuItem,
                    Name = name,
                    OrderBy = orderBy,
                    OrderDirection = orderDirection,
                    ViewString = viewString,
                    User = u
                };

                Apollo.Application.CurrentSession.Save(uv);

                tran.Commit();

                MessageList.AddMessage(new ActionMessage("View saved!", ActionMessageType.Info));

                Apollo.Application.ClearSession();

                Response.Redirect(string.Format("~/View.aspx?MenuId={0}&UserViewId={1}", SelectedMenuItem.Id, uv.Id));
            }
            catch (Exception ex)
            {
                tran.Rollback();

                MessageList.AddMessage(new ActionMessage("Save failed: " + ex.Message, ActionMessageType.Error));
            }
        }

        protected void OnUserViewDel()
        {
            ITransaction tran = Apollo.Application.CurrentSession.BeginTransaction();

            try
            {
                Apollo.Application.CurrentSession.Delete(EntityGridView.UserView);

                tran.Commit();

                MessageList.AddMessage(new ActionMessage("View deleted!", ActionMessageType.Info));

                Apollo.Application.ClearSession();

                Response.Redirect(string.Format("~/View.aspx?MenuId={0}", SelectedMenuItem.Id));
            }
            catch (Exception ex)
            {
                tran.Rollback();

                MessageList.AddMessage(new ActionMessage("Delete failed: " + ex.Message, ActionMessageType.Error));
            }
        }
    }

}